package map.adapter;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import org.eclipse.emf.ecore.util.EcoreUtil;

import map.tools.uimodel.WidgetsModelsSerializer;
import uimigration.Interactions.Behaviour;
import uimigration.Plateform.Plateform;
import uimigration.UIModel.Container;
import uimigration.UIModel.Event;
import uimigration.UIModel.UIElement;
import uimigration.WidgetsModel.Widget;
import uimigration.WidgetsModel.util.WidgetsModelManager;

public class WidgetsFinder {
	private List<uimigration.WidgetsModel.Widget> listWEqual;
	private List<uimigration.WidgetsModel.Widget> listWEquivalent;
	private List<uimigration.WidgetsModel.Widget> listWTypeEquivalent;
	private WidgetsModelManager manager;
	private WidgetManager wmanager;
	private Plateform plateform;
	private int MAX_EQUIVALENT_WIDGET=5;
	private boolean DEBUG=true;;
	
	public WidgetsFinder(String fileName,String  apiSoure){
		manager= new WidgetsModelManager( new WidgetsModelsSerializer().load(new File(fileName)));
		wmanager= new WidgetManager(fileName,apiSoure);
	}
	public List<uimigration.WidgetsModel.Widget> find(UIElement element){
		List<uimigration.WidgetsModel.Widget> found= new ArrayList<Widget>();
		Widget w = element.getWidgetType();
		if(w!=null)
		{
			listWEqual=null;listWEquivalent=null;listWTypeEquivalent=null;
			listWEqual= manager.findEqualWidget(w);
			if( listWEqual.size()<MAX_EQUIVALENT_WIDGET)
			{
				listWEquivalent= manager.findEquivalentWidgets(w);
				if( (listWEqual.size()+listWEquivalent.size())< MAX_EQUIVALENT_WIDGET)
					listWTypeEquivalent= manager.findTypeEquivalentWidgets(w);
			}
			for(int i=0;i<MAX_EQUIVALENT_WIDGET;i++)
				if(listWEqual!=null&&listWEqual.size()>0)
				{
					Widget wi=listWEqual.remove(0);
					if(!contains(found, wi))
						found.add(wi);
				}
				else if(listWEquivalent!=null && listWEquivalent.size()>0)
				{
					Widget wi=listWEquivalent.remove(0);
					if(!contains(found, wi))
						found.add(wi);
				}
				else if(listWTypeEquivalent!=null && listWTypeEquivalent.size()>0)
				{
					Widget wi=listWTypeEquivalent.remove(0);
					if(!contains(found, wi))
						found.add(wi);
				}

			if(found!=null && DEBUG)
				System.out.println("Test  find: "+testFind(w,found));
		}

		return found;
	}

	public List<uimigration.WidgetsModel.Widget> find2(UIElement element){
		List<uimigration.WidgetsModel.Widget> found= new ArrayList<Widget>();
		Widget w = element.getWidgetType();
		if(w!=null)
		{
			boolean  root, container;
			List<uimigration.WidgetsModel.Widget>  listW= null;
			if(hasMoreImplementedBehavior(element, w))
			{	try{
					root=((Container)element).isIsRoot();
					container=true;
				}catch(ClassCastException e)
				{
					root=false;
					container= false;
				}
				listW=wmanager.findEquivalenImplementedtWidgets(root, container, w.getCardinality(), getImplementedEvent(element), element.getWidgetType());
				
			}
			else
				listW= wmanager.findEquivalentWidgets(w);
			int i=0;
			while (i<MAX_EQUIVALENT_WIDGET && i<listW.size())
			{
				found.add(EcoreUtil.copy(listW.get(i)));
				i++;
			}
		}
		
		if(found!=null && DEBUG)
			System.out.println("Test  find: "+testFind(w,found));
		return found;
	}
	
	private boolean contains(List<uimigration.WidgetsModel.Widget> found, Widget w)
	{
		for(Widget wi:found){
			if(w.getName().equals(wi.getName()))
				return true;
		}
		return false;
	}

	public boolean hasMoreImplementedBehavior(UIElement element, Widget type)
	{
		Vector<String> impB= new Vector<String>();
		if(element.getEvents()!=null)
			for(Event e : element.getEvents())
				if(e.getImplementedEventBehaviour()!=null)
					for(Behaviour bi : e.getImplementedEventBehaviour())
						if(!impB.contains( bi.eClass().getName()))
								impB.add(bi.eClass().getName());
		if(type.getEvents()!=null)
			for(Behaviour bi : type.getBehavior())
				if(impB.contains( bi.eClass().getName()))
					impB.remove( bi.eClass().getName());
		if(impB!=null && impB.size()>0)
			return true;
		return false;
	}
	public List<Behaviour> getImplementedEvent(UIElement element)
	{
		List<Behaviour> l= new ArrayList<Behaviour>();
		Vector<String> st= new Vector<String>();
		for(Event e: element.getEvents()){
			if(e.getImplementedEventBehaviour()!=null)
				for(Behaviour b : e.getImplementedEventBehaviour())
				{
					if(!st.contains(b.eClass().getName()))
					{		
						st.add(b.eClass().getName());
						l.add(b);
					}		
				}
		}
		return l;
	}
	public void setListWEqual(List<uimigration.WidgetsModel.Widget> listWEqual) {
		this.listWEqual = listWEqual;
	}
	public List<uimigration.WidgetsModel.Widget> getListWEqual() {
		return listWEqual;
	}
	public void setListWEquivalent(List<uimigration.WidgetsModel.Widget> listWEquivalent) {
		this.listWEquivalent = listWEquivalent;
	}
	public List<uimigration.WidgetsModel.Widget> getListWEquivalent() {
		return listWEquivalent;
	}
	public void setListWTypeEquivalent(List<uimigration.WidgetsModel.Widget> listWTypeEquivalent) {
		this.listWTypeEquivalent = listWTypeEquivalent;
	}
	public List<uimigration.WidgetsModel.Widget> getListWTypeEquivalent() {
		return listWTypeEquivalent;
	}
	public void setPlateform(Plateform plateform) {
		this.plateform = plateform;
	}
	public Plateform getPlateform() {
		return plateform;
	}
	public int getMAX_EQUIVALENT_WIDGET() {
		return MAX_EQUIVALENT_WIDGET;
	}
	public void setMAX_EQUIVALENT_WIDGET(int max_equivalent_widget) {
		MAX_EQUIVALENT_WIDGET = max_equivalent_widget;
	}

	public String testFind(Widget looking,List<Widget> found)
	{
		String ret="";
		ret+="Looking for :"+looking.getName()+" "+looking.getId()+" isContainer="+looking.isIsContainer()+"\n";
		for(Behaviour b:looking.getBehavior())
			ret+="-"+b.getClass().getSimpleName()+"\n";
		ret+="Found :\n";
		for(Widget w:found){
			ret+="+"+w.getName()+" "+w.getId()+" isContainer="+w.isIsContainer()+"\n";
			for(Behaviour bi:w.getBehavior())
				ret+=bi.getClass().getSimpleName()+"\n";
		}
		
		return ret;
	}
	public String displayUIElement(UIElement e){
		
		String s="displayUIElement ";
		if(e!=null)
		{	
			s+=e.toString();
			List<Behaviour> lb=e.getWidgetType().getBehavior();
			for(Behaviour b :lb )
				s+="+ "+b.getClass().getSimpleName();
		}
		return s;
	}
	
}
